import 'dart:async';
import 'dart:convert';
import 'dart:typed_data';
import 'package:lovify/core/constants/config.dart';
import 'package:lovify/models/enums/im_state.dart';
import 'package:lovify/models/enums/im_type.dart';
import 'package:lovify/models/message.dart';
import 'package:web_socket_channel/web_socket_channel.dart';
import 'package:logger/logger.dart';
import 'package:lovify/core/ws/abstract_im.dart';
import 'package:lovify/models/im_message.dart';

class BaseIM<T> extends AbstractIM<IMMessage<T>> {
  final WebSocketChannel channel;
  final _messageController = StreamController<IMMessage<T>>.broadcast();
  final Logger _logger = Logger(printer: PrettyPrinter());

  BaseIM(String url) : channel = WebSocketChannel.connect(Uri.parse(url));

  @override
  Stream<IMMessage<T>> get messages => _messageController.stream;

  @override
  void sendMessage(IMMessage<T> message) {
    try {
      final messageJson = message.toJson();
      channel.sink.add(messageJson);
      _logger.i("消息已发送: ${message.payload}");
    } catch (e) {
      _logger.e("发送消息失败: $e");
    }
  }

  @override
  void connect() {
    try {
      channel.stream.listen(
        (data) {
          _logger.i("接收到消息: $data");

          try {
            final decoded = jsonDecode(data);
            final message = IMMessage<T>(
              state: _parseIMState(decoded['state']),
              payload: _parsePayload(decoded['payload']),
            );
            _messageController.add(message);
          } catch (e) {
            _logger.e("消息解析失败: $e");
          }
        },
        onError: (error) {
          _logger.e("WebSocket 连接出错: $error");
        },
        onDone: () {
          _logger.i("WebSocket 连接已关闭");
        },
      );
      _logger.i("成功连接到 WebSocket 服务器");
    } catch (e) {
      _logger.e("连接失败: $e");
    }
  }

  @override
  void disconnect() {
    try {
      channel.sink.close();
      _logger.i("与 WebSocket 服务器的连接已断开");
    } catch (e) {
      _logger.e("断开连接失败: $e");
    }
  }

  IMState _parseIMState(dynamic state) {
    try {
      if (state == null) return IMState.normal;
      if (state is int) {
        return IMState.values
            .firstWhere((e) => e.index == state, orElse: () => IMState.normal);
      }
      return IMState.normal;
    } catch (e) {
      _logger.e("解析 IMState 时出错: $e");
      return IMState.normal;
    }
  }

  _parsePayload(dynamic payload) {
    if (T == Uint8List) {
      return Uint8List.fromList(payload) as T;
    } else if (T == Message) {
      return Message.fromJson(payload) as T;
    } else {
      throw Exception("不支持的 payload 类型: $T");
    }
  }

  static String url(IMType type, String from, String to) {
    String path;
    switch (type) {
      case IMType.voice:
        path = "/chat/voice/$from/$to";
        break;
      case IMType.video:
        path = "/chat/video/$from/$to";
        break;
      default:
        path = "/chat/text/$from/$to";
        break;
    }
    return "$baseWsUrl$path";
  }
}
